package com.godenwater.yanyu;

import org.apache.commons.lang3.StringUtils;

import com.godenwater.yanyu.utils.ByteUtil;

/**
 * 水文协议构建工具，通过此类可以构建查询消息体
 * 
 * @author admin
 *
 */
public class YYBuilder {

	public static String buildDot(String value, int decimal) {
		if (StringUtils.isNotBlank(value)) {
			value = value.trim();
			int len = value.length();
			if (decimal == 0)
				return value;
			if (len > decimal) {
				String right = value.substring(len - decimal);
				int pos = StringUtils.lastIndexOf(value, right);
				String left = value.substring(0, pos);
				return left + "." + right;
			} else {
				value = StringUtils.leftPad(value, decimal, "0");
				value = "0." + value;
				return value;
			}
		}
		return "";
	}

	public static int buildDecimal(String value) {
		int end = 0;
		int pos = value.indexOf(".");
		if (pos != -1) {
			String endstr = value.substring(pos + 1);
			end = endstr.length();
		}

		return end;
	}

	/**
	 * 合成数据标识符“低位字节”的数据位字节
	 * 
	 * @param value
	 */
	public static byte buildDataLength(int len, int decimal) {
		// 开始合并,数据位的位数
		byte hignByte = ByteUtil.ubyteToBytes(len)[0];
		byte lowByte = ByteUtil.ubyteToBytes(decimal)[0];

		byte high = (byte) ((hignByte << 3) & 0xF8);
		byte low = (byte) (lowByte & 0x07);

		return (byte) (high | low);
	}

	/**
	 * 起始位
	 */
	public static void newStartBit(IMessageHeader header) {
		byte[] startBit = new byte[header.getStartBitLen()];
		startBit[0] = Symbol.SOH;
		header.setStartBit(startBit);
	}

	/**
	 * 中心站地址
	 * 
	 * 取值范围为1-255，对于ASCII模式，需要将1字节的HEX编码转换为两个字符进行传输
	 * 
	 * 因为取值范围为1-255，默认相当于为16进制的数。
	 */
	public static void newCenterAddr(IMessageHeader header, int value) {
		byte[] centerAddr = new byte[header.getCenterAddrLen()];

		// HEX编码，value相当于16进制的数,// 需将其转换为字符FF
		String temp = Integer.toHexString(value);
		centerAddr = temp.getBytes();

		header.setCenterAddr(centerAddr);
	}

	public static void newCenterAddr(IMessageHeader header, byte[] value) {
		// HEX编码，value相当于16进制的数
		header.setCenterAddr(value);
	}

	/**
	 * 遥测站地址
	 * 
	 */
	public static void newStationAddr(IMessageHeader header, int value) {
		byte[] stationAddr = new byte[header.getStationAddrLen()];

		// HEX编码，value相当于16进制的数,// 需将其转换为字符FF
		String temp = Integer.toHexString(value);
		stationAddr = temp.getBytes();

		header.setStationAddr(stationAddr);

	}

	public static void newStationAddr(IMessageHeader header, byte[] stationAddr) {
		header.setStationAddr(stationAddr);
	}

	/**
	 * 功能码
	 */
	public static void newFuncCode(IMessageHeader header, String value) {
		byte[] funcCode = new byte[header.getFuncCodeLen()];

		// HEX编码，value相当于16进制的数
		if (header.getStartBitLen() == 2) {
			int valueint = Integer.parseInt(value, 16);
			funcCode = ByteUtil.ubyteToBytes(valueint);
		} else {
			funcCode = value.getBytes();
		}

		header.setFuncCode(funcCode);
	}

	public static void newFuncCode(IMessageHeader header, byte[] funccode) {

		header.setFuncCode(funccode);
	}

	/**
	 * 报文上下行标识及长度
	 */
	public static void newBodySize(IMessageHeader header, int length) {
		// HEX编码，value相当于16进制的数

		byte[] bodySize = ByteUtil.ubyteToBytes(length);
		header.setBodySize(bodySize);
	}

	/**
	 * 报文结束符
	 */
	public static void newMessageEOF(IMessage message, String value) {
		// byte[] eof = new byte[1];
		// eof[0] = Symbol.STX;
		byte[] eof = ByteUtil.HexStringToBinary(value);
		message.setEOF(eof[0]);
	}

	/**
	 * 报文校验码
	 */
	public static void newMessageCRC(IMessage message, String value) {
		byte[] crc = ByteUtil.HexStringToBinary(value);
		message.setCRC(crc);
	}

	public static String toHexString(IMessageHeader header, byte updown) {
		StringBuffer sb = new StringBuffer(header.getLength());
		sb.append(ByteUtil.toHexString(header.getStartBit()));
		if (Symbol.UP == updown) {
			sb.append(ByteUtil.toHexString(header.getCenterAddr()));
			sb.append(ByteUtil.toHexString(header.getStationAddr()));
		} else {
			sb.append(ByteUtil.toHexString(header.getStationAddr()));
			sb.append(ByteUtil.toHexString(header.getCenterAddr()));
		}
		sb.append(ByteUtil.toHexString(header.getFuncCode()));
		sb.append(ByteUtil.toHexString(header.getBodySize()));

		return sb.toString();
	}

	public static String toHexString(IMessage message, byte updown) {
		StringBuffer sb = new StringBuffer();
		sb.append(toHexString(message.getHeader(), updown));
		sb.append(ByteUtil.toHexString(message.getBody().getContent())
				.toUpperCase());
		sb.append(ByteUtil.toHexString(message.getEOF()));
		sb.append(ByteUtil.toHexString(message.getCRC()));
		return sb.toString().toUpperCase();
	}

	public static byte[] toByte(IMessage message, byte updown) {

		IMessageHeader header = message.getHeader();
		IMessageBody body = message.getBody();

		int crclen = 2;
		int size = header.getLength() + body.getLength() + 1 + crclen;
		byte[] content = new byte[size];

		int pos = 0;
		System.arraycopy(header.getStartBit(), 0, content, pos,
				header.getStartBitLen());
		pos = pos + header.getStartBitLen();

		if (Symbol.UP == updown) {
			System.arraycopy(header.getCenterAddr(), 0, content, pos,
					header.getCenterAddrLen());
			pos = pos + header.getCenterAddrLen();
			System.arraycopy(header.getStationAddr(), 0, content, pos,
					header.getStationAddrLen());
			pos = pos + header.getStationAddrLen();

		} else {

			System.arraycopy(header.getStationAddr(), 0, content, pos,
					header.getStationAddrLen());
			pos = pos + header.getStationAddrLen();
			System.arraycopy(header.getCenterAddr(), 0, content, pos,
					header.getCenterAddrLen());
			pos = pos + header.getCenterAddrLen();
		}
		// ---------------------------------

		System.arraycopy(header.getFuncCode(), 0, content, pos,
				header.getFuncCodeLen());
		pos = pos + header.getFuncCodeLen();
		// ---------------------------------
		System.arraycopy(header.getBodySize(), 0, content, pos,
				header.getBodySizeLen());
		pos = pos + header.getBodySizeLen();
		// ---------------------------------
		if (body.getContent() != null) {
			System.arraycopy(body.getContent(), 0, content, pos, body.getLength());
			pos = pos + body.getLength();
		}
		// ---------------------------------
		System.arraycopy(new byte[] { message.getEOF() }, 0, content, pos, 1);
		pos = pos + 1;
		// ---------------------------------
		System.arraycopy(message.getCRC(), 0, content, pos,
				message.getCRC().length);

		return content;
	}

	public static void main(String[] args) {
		// HydroBuilder.newStartBut

		IMessageHeader yyHeader = new YYMessageHeader();
		YYBuilder.newCenterAddr(yyHeader, 255); // 1-255,按十六进制数输入
		System.out.println(ByteUtil.toHexString(yyHeader.getCenterAddr()));

		System.out.println("---------------------------------");
		String xxx = "43484C5B305D2D3E6765742061206E657720736D73200D0A";
		String yyy = "112233";

		new String(xxx.getBytes());//

		byte[] b = yyy.getBytes();

		System.out.println(new String(ByteUtil.HexStringToBinary(xxx)));

		// byte lllleeennn = HydroBuilder.buildDataLength(4, 0);
		// System.out.println("lllleeennn = " +
		// ByteUtil.toHexString(lllleeennn));
		//
		// System.out.println("value = " + ByteUtil.toBinaryString((byte)
		// 0x01));
		// for (int i = 0; i < 5; i++) {
		// String value = HydroBuilder.buildDot("000030", i);
		// System.out.println("value = " + value);
		// }
		// String upDown = "DOWN";
		//
		// // 报文正文
		// Up2FBody body = new Up2FBody();
		// // 流水号 ，取值范围01 - 65535
		// body.setSerialId(0);
		//
		// // 发报时间
		// SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");
		// body.setSendDate(sdf.format(new Date()));
		// byte[] dest = body.getContent();
		//
		// System.out.println(">> body hex " + Integer.MAX_VALUE);
		//
		// // 报文头
		// HexHeader header = new HexHeader();
		// HydroBuilder.newStartBit(header);
		// HydroBuilder.newCenterAddr(header, "255"); // 1-255,按十六进制数输入
		// HydroBuilder.newStationAddr(header, "12345678");
		// HydroBuilder.newPassword(header, "FFFF");
		// HydroBuilder.newFuncCode(header, "37");
		// HydroBuilder.newBodyLength(header, Symbol.UP, body.getLength());
		// HydroBuilder.newBodyStartBit(header, new byte[] { Symbol.STX });
		//
		// HydroMessage message = new HydroMessage();
		// message.setHeader(header);
		// message.setBody(body);
		// message.setEOF(Symbol.ENQ);
		// // message.setCRC(crc);
		// //
		// // String hexStr = HydroBuilder.toDownHexString(header);
		// // System.out.print(">> hex " + hexStr.toUpperCase());
		// // System.out.print("" + ByteUtil.toHexString(body.getContent()));
		// // System.out.print("" + ByteUtil.toHexString(message.getEOF()));
		// //
		// // // 7E7E0012345678FFFFFF37800802000013022511461705
		// // String crc = CRC16Helper.crc16Check(HydroBuilder
		// // .toDownHexString(header)
		// // + ByteUtil.toHexString(body.getContent())
		// // + ByteUtil.toHexString(message.getEOF()));
		// // System.out.print("  " + crc);
		// //
		// // message.setCRC(ByteUtil.HexStringToBinary(crc));

	}
}
